#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_chessBoard(new chessboard)
{
    ui->setupUi(this);

    /* 设置图标 */
    setWindowIcon(QIcon(":/image/chess.png"));

    /* 设置标题 */
    setWindowTitle("卷客Coder中国象棋");
    setFixedSize(1100, 1100);

    /* 设置布局 —— 解决棋盘绘制问题 */
    QWidget * centerWidget = new QWidget(this);
    setCentralWidget(centerWidget);
    QVBoxLayout *layout = new QVBoxLayout(centerWidget);
    layout->addWidget(m_chessBoard);

    /* 设置按钮外观 */
    QFont font;
    font.setFamily("Arial"); // 设置字体族
    font.setPointSize(14);   // 设置字体大小
    font.setBold(true);      // 设置字体为粗体
    font.setItalic(false);   // 设置字体不为斜体

    QPushButton *startBtn = new QPushButton("开始游戏", this);
    startBtn->resize(120, 60);
    startBtn->move(925, 200);
    startBtn->setFont(font);

    QPushButton *restartBtn = new QPushButton("重新开始", this);
    restartBtn->resize(120, 60);
    restartBtn->move(925, 400);
    restartBtn->setFont(font);

    QPushButton *backBtn = new QPushButton("悔棋", this);
    backBtn->resize(120, 60);
    backBtn->move(925, 600);
    backBtn->setFont(font);

    redLabel = new QLabel(this);
    redLabel->resize(120, 60);
    redLabel->move(925, 80);
    redLabel->setText("红方回合");
    redLabel->hide();
    redLabel->setStyleSheet("QLabel {"
                                "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #2196F3, stop:1 #4CAF50);"
                                "color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #ffffff, stop:1 #f44336);"
                                "font: 22px 'Segoe UI';"
                                "padding: 15px;"
                                "border-radius: 8px;"
                                "text-align: center;"
                                "}");

    blackLabel = new QLabel(this);
    blackLabel->resize(120, 60);
    blackLabel->move(925, 720);
    blackLabel->setText("黑方回合");
    blackLabel->hide();
    blackLabel->setStyleSheet("QLabel {"
                                "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #2196F3, stop:1 #4CAF50);"
                                "color: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #ffffff, stop:1 #f44336);"
                                "font: 22px 'Segoe UI';"
                                "padding: 15px;"
                                "border-radius: 8px;"
                                "text-align: center;"
                                "}");


    connect(m_chessBoard, &chessboard::cellClicked, this, &MainWindow::handleCellClicked);
    connect(m_chessBoard, &chessboard::whereShow, this, &MainWindow::whereShow);

    connect(startBtn, &QPushButton::clicked, this, &MainWindow::handleStart);
    connect(restartBtn, &QPushButton::clicked, this, &MainWindow::handleRestart);
    connect(backBtn, &QPushButton::clicked, this, &MainWindow::handleRepentance);
}

/* 判断走棋是否合规 */
void MainWindow::handleCellClicked(int oldRow, int oldCol, int row, int col)
{
    Chess old = m_chessBoard->getPointVal(oldRow, oldCol);

    int dx = row - oldRow;
    int dy = col - oldCol;

    switch (old)
    {
    case RedCart:
    {
        if (dx == 0 && dy != 0)
        {
            int minY = std::min(col, oldCol);
            int maxY = std::max(col, oldCol);
            for (int idx = minY + 1; idx < maxY; idx++)
            {
                if (m_chessBoard->getPointVal(oldRow, idx) != EMPTY)
                {
                    return;
                }
            }
            if (m_chessBoard->isRed(row, col) == false)
            {
                m_chessBoard->setValid();
            }
        }
        else if (dx != 0 && dy == 0)
        {
            int minX = std::min(row, oldRow);
            int maxX = std::max(row, oldRow);
            for (int idx = minX + 1; idx < maxX; idx++)
            {
                if (m_chessBoard->getPointVal(idx, oldCol) != EMPTY)
                {
                    return;
                }
            }
            if (m_chessBoard->isRed(row, col) == false)
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case RedHorse:
    {
        if ((abs(dx) == 1 && abs(dy) == 2) || (abs(dx) == 2 && abs(dy) == 1))
        {
            if (abs(dx) == 2 && m_chessBoard->getPointVal((row - dx / 2), oldCol) == EMPTY && (m_chessBoard->isRed(row, col) == false))
            {
                m_chessBoard->setValid();
            }
            if (abs(dy) == 2 && m_chessBoard->getPointVal(oldRow, (col - dy / 2)) == EMPTY && (m_chessBoard->isRed(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case RedPhase:
    {
        if (col >= 0 && col <= 4 && abs(dx) == 2 && abs(dy) == 2)
        {
            if (m_chessBoard->getPointVal((row - dx / 2), (col - dy / 2)) == EMPTY && (m_chessBoard->isRed(row, col) == false))     //撇象脚
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case RedChevalier:
    {
        if ((row >= 3 && row <= 5) && (col >= 0 && col <= 2) && abs(dx) == 1 && abs(dy) == 1 && (m_chessBoard->isRed(row, col) == false))
        {
            m_chessBoard->setValid();
        }
    }
        break;
    case RedGenerals:
    {
        if ((row >= 3 && row <= 5) && (col >= 0 && col <= 2) && (abs(dx) + abs(dy)) == 1 && (m_chessBoard->isRed(row, col) == false))
        {
            m_chessBoard->setValid();
        }
    }
        break;
    case RedSoldier:
    {
        if (oldCol <= 4 && dx == 0 && dy == 1 && (m_chessBoard->isRed(row, col) == false))
        {
            m_chessBoard->setValid();
        }
        else if (oldCol >= 5 && ((dx == 0 && dy == 1) || (abs(dx) == 1 && dy == 0)) && (m_chessBoard->isRed(row, col) == false))
        {
            m_chessBoard->setValid();
        }
    }
        break;
    case RedCannon:
    {
        int count = 0;
        if (dx == 0 && dy != 0)
        {
            int minY = std::min(col, oldCol);
            int maxY = std::max(col, oldCol);
            for (int idx = minY + 1; idx < maxY; idx++)
            {
                if (m_chessBoard->getPointVal(oldRow, idx) != EMPTY)
                {
                    count++;
                }
            }

            if (((count == 0 && m_chessBoard->getPointVal(row, col) == EMPTY) || (count == 1 && m_chessBoard->getPointVal(row, col) != EMPTY)) && (m_chessBoard->isRed(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
        else if (dx != 0 && dy == 0)
        {
            int minX = std::min(row, oldRow);
            int maxX = std::max(row, oldRow);
            for (int idx = minX + 1; idx < maxX; idx++)
            {
                if (m_chessBoard->getPointVal(idx, oldCol) != EMPTY)
                {
                    count++;
                }
            }

            if (((count == 0 && m_chessBoard->getPointVal(row, col) == EMPTY) || (count == 1 && m_chessBoard->getPointVal(row, col) != EMPTY)) && (m_chessBoard->isRed(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case BlackCart:
    {
        if (dx == 0 && dy != 0)
        {
            int minY = std::min(col, oldCol);
            int maxY = std::max(col, oldCol);
            for (int idx = minY + 1; idx < maxY; idx++)
            {
                if (m_chessBoard->getPointVal(oldRow, idx) != EMPTY)
                {
                    return;
                }
            }
            if (m_chessBoard->isBlack(row, col) == false)
            {
                m_chessBoard->setValid();
            }
        }
        else if (dx != 0 && dy == 0)
        {
            int minX = std::min(row, oldRow);
            int maxX = std::max(row, oldRow);
            for (int idx = minX + 1; idx < maxX; idx++)
            {
                if (m_chessBoard->getPointVal(idx, oldCol) != EMPTY)
                {
                    return;
                }
            }
            if (m_chessBoard->isBlack(row, col) == false)
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case BlackHorse:
    {
        if ((abs(dx) == 1 && abs(dy) == 2) || (abs(dx) == 2 && abs(dy) == 1))
        {
            if (abs(dx) == 2 && m_chessBoard->getPointVal((row - dx / 2), oldCol) == EMPTY && (m_chessBoard->isBlack(row, col) == false))
            {
                m_chessBoard->setValid();
            }
            if (abs(dy) == 2 && m_chessBoard->getPointVal(oldRow, (col - dy / 2)) == EMPTY && (m_chessBoard->isBlack(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case BlackPhase:
    {
        if (col >= 5 && col <= 9 && abs(dx) == 2 && abs(dy) == 2)
        {
            if (m_chessBoard->getPointVal((row - dx / 2), (col - dy / 2)) == EMPTY && (m_chessBoard->isBlack(row, col) == false))     //撇象脚
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    case BlackChevalier:
    {
        if ((row >= 3 && row <= 5) && (col >= 7 && col <= 9) && abs(dx) == 1 && abs(dy) == 1 && (m_chessBoard->isBlack(row, col) == false))
        {
            m_chessBoard->setValid();
        }
    }
        break;
    case BlackGenerals:
    {
        if ((row >= 3 && row <= 5) && (col >= 7 && col <= 9) && (abs(dx) + abs(dy)) == 1 && (m_chessBoard->isBlack(row, col) == false))
        {
           m_chessBoard->setValid();
        }
    }
        break;
    case BlackSoldier:
    {
        if (oldCol >= 5 && dx == 0 && dy == -1 && (m_chessBoard->isBlack(row, col) == false))
        {
            m_chessBoard->setValid();
        }
        else if (oldCol <= 4 && ((dx == 0 && dy == -1) || (abs(dx) == 1 && dy == 0)) && (m_chessBoard->isBlack(row, col) == false))
        {
            m_chessBoard->setValid();
        }
    }
        break;
    case BlackCannon:
    {
        int count = 0;
        if (dx == 0 && dy != 0)
        {
            int minY = std::min(col, oldCol);
            int maxY = std::max(col, oldCol);
            for (int idx = minY + 1; idx < maxY; idx++)
            {
                if (m_chessBoard->getPointVal(oldRow, idx) != EMPTY)
                {
                    count++;
                }
            }

            if (((count == 0 && m_chessBoard->getPointVal(row, col) == EMPTY) || (count == 1 && m_chessBoard->getPointVal(row, col) != EMPTY)) && (m_chessBoard->isBlack(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
        else if (dx != 0 && dy == 0)
        {
            int minX = std::min(row, oldRow);
            int maxX = std::max(row, oldRow);
            for (int idx = minX + 1; idx < maxX; idx++)
            {
                if (m_chessBoard->getPointVal(idx, oldCol) != EMPTY)
                {
                    count++;
                }
            }

            if (((count == 0 && m_chessBoard->getPointVal(row, col) == EMPTY) || (count == 1 && m_chessBoard->getPointVal(row, col) != EMPTY)) && (m_chessBoard->isBlack(row, col) == false))
            {
                m_chessBoard->setValid();
            }
        }
    }
        break;
    }
}

/* 点击开始游戏按钮 */
void MainWindow::handleStart()
{
    for (int idx = 0; idx < m_chessBoard->getCol(); idx++)
    {
        for (int jdx = 0; jdx < m_chessBoard->getRow(); jdx++)
        {
            if (m_chessBoard->getPointVal(idx, jdx) != EMPTY)
            {
                m_chessBoard->setPointVal(idx, jdx, EMPTY);
            }
        }
    }

    m_chessBoard->setPointVal(0, 0, RedCart);
    m_chessBoard->setPointVal(1, 0, RedHorse);
    m_chessBoard->setPointVal(2, 0, RedPhase);
    m_chessBoard->setPointVal(3, 0, RedChevalier);
    m_chessBoard->setPointVal(4, 0, RedGenerals);
    m_chessBoard->setPointVal(5, 0, RedChevalier);
    m_chessBoard->setPointVal(6, 0, RedPhase);
    m_chessBoard->setPointVal(7, 0, RedHorse);
    m_chessBoard->setPointVal(8, 0, RedCart);
    m_chessBoard->setPointVal(1, 2, RedCannon);
    m_chessBoard->setPointVal(7, 2, RedCannon);
    m_chessBoard->setPointVal(0, 3, RedSoldier);
    m_chessBoard->setPointVal(2, 3, RedSoldier);
    m_chessBoard->setPointVal(4, 3, RedSoldier);
    m_chessBoard->setPointVal(6, 3, RedSoldier);
    m_chessBoard->setPointVal(8, 3, RedSoldier);

    m_chessBoard->setPointVal(0, 9, BlackCart);
    m_chessBoard->setPointVal(1, 9, BlackHorse);
    m_chessBoard->setPointVal(2, 9, BlackPhase);
    m_chessBoard->setPointVal(3, 9, BlackChevalier);
    m_chessBoard->setPointVal(4, 9, BlackGenerals);
    m_chessBoard->setPointVal(5, 9, BlackChevalier);
    m_chessBoard->setPointVal(6, 9, BlackPhase);
    m_chessBoard->setPointVal(7, 9, BlackHorse);
    m_chessBoard->setPointVal(8, 9, BlackCart);
    m_chessBoard->setPointVal(1, 7, BlackCannon);
    m_chessBoard->setPointVal(7, 7, BlackCannon);
    m_chessBoard->setPointVal(0, 6, BlackSoldier);
    m_chessBoard->setPointVal(2, 6, BlackSoldier);
    m_chessBoard->setPointVal(4, 6, BlackSoldier);
    m_chessBoard->setPointVal(6, 6, BlackSoldier);
    m_chessBoard->setPointVal(8, 6, BlackSoldier);

    m_chessBoard->initialize();

    redLabel->show();
    blackLabel->hide();
    m_chessBoard->update();
}

/* 点击重新开始按钮 */
void MainWindow::handleRestart()
{
    handleStart();
}

/* 点击悔棋按钮 */
void MainWindow::handleRepentance()
{
    m_chessBoard->removeSteps();
}

/* 在哪显示标签 */
void MainWindow::whereShow()
{
    if (m_chessBoard->isRed() == true)
    {
        redLabel->show();
        blackLabel->hide();
    }
    else
    {
        redLabel->hide();
        blackLabel->show();
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}
